#include "orangepch.h"
#include "OpenGlFrameBuffer.h"
#include "glad/glad.h"
#include "Core/Log.h"
namespace Orange {

	static uint32_t s_MaxFrameBufferWidth = 8192;

	OpenGlFrameBuffer::OpenGlFrameBuffer(const FrameBufferSpecification& spec):m_Specification(spec)
	{
		Invalidate();
	}

	OpenGlFrameBuffer::~OpenGlFrameBuffer()
	{
		glDeleteFramebuffers(1, &m_RendererId);
		glDeleteTextures(1, &m_ColorAttachment);
		glDeleteTextures(1, &m_DepthAttachment);
		
	}

	void OpenGlFrameBuffer::Bind()
	{
		glBindFramebuffer(GL_FRAMEBUFFER, m_RendererId);
		glViewport(0, 0, m_Specification.width, m_Specification.height);
	}

	void OpenGlFrameBuffer::UnBind()
	{
		 glBindFramebuffer(GL_FRAMEBUFFER, 0);
	}

	void OpenGlFrameBuffer::Resize(uint32_t width, uint32_t height)
	{

		if ( width == 0 || height == 0 || width > s_MaxFrameBufferWidth || height > s_MaxFrameBufferWidth) {
			ORANGE_CORE_WARN(" Attempting to change window {0} , {1} ",width , height);
			return;
		}

		m_Specification.width = width;
		m_Specification.height = height;


		Invalidate();
	}

	void OpenGlFrameBuffer::Invalidate()
	{

		if (m_RendererId) {
			// �������һ֡���� �����һ��
			glDeleteFramebuffers(1, &m_RendererId);
			glDeleteTextures(1, &m_ColorAttachment);
			glDeleteTextures(1, &m_DepthAttachment);

		}

		glCreateFramebuffers(1, &m_RendererId);
		glBindFramebuffer(GL_FRAMEBUFFER, m_RendererId);

		/// <summary>
		/// ��ɫ
		/// </summary>
		glCreateTextures(GL_TEXTURE_2D, 1, &m_ColorAttachment);
		glBindTexture(GL_TEXTURE_2D, m_ColorAttachment);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Specification.width, m_Specification.height,
			0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_ColorAttachment, 0);
		
		/// <summary>
		/// ���
		/// </summary>
		glCreateTextures(GL_TEXTURE_2D, 1, &m_DepthAttachment);
		glBindTexture(GL_TEXTURE_2D, m_DepthAttachment);
		glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, m_Specification.width, m_Specification.height);

 		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthAttachment, 0);

		ORANGE_CORE_ASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Framebuffer is incomplete");


		glBindFramebuffer(GL_FRAMEBUFFER, 0);

	}


	void OpenGlFrameBuffer::ClearAttachment(int value)
	{
	
		glClearTexImage(m_ColorAttachment, 0,
			GL_RED_INTEGER, GL_INT, &value);
	}
}
